/**
 * @file bsp_BDC_motor.c
 * @author your name (you@domain.com)
 * @brief 直流电机驱动
 * @version 0.2
 * @date 2022-07-7
 * 
 * @copyright Copyright (c) 2022
 * 
 */
#include <stdlib.h>
#include "bsp_BDC_motor.h"
#include "stm32f4xx_hal.h"
// #include "gpio_config.h"
#include "timer_config.h"

// void motorInit(void);
// void setMotorDir(motor_dir_e motor_dir);


/* 设置速度（占空比） */
#define SET_FWD_COMPAER(ChannelPulse) TIM3_SetPWM_pulse(PWM_CHANNEL_1, ChannelPulse) // 设置比较寄存器的值
#define SET_REV_COMPAER(ChannelPulse) TIM3_SetPWM_pulse(PWM_CHANNEL_2, ChannelPulse) // 设置比较寄存器的值

/* 使能输出 */
#define MOTOR_FWD_ENABLE() HAL_TIM_PWM_Start(&htim3, PWM_CHANNEL_1)
#define MOTOR_REV_ENABLE() HAL_TIM_PWM_Start(&htim3, PWM_CHANNEL_2)

/* 禁用输出 */
#define MOTOR_FWD_DISABLE() HAL_TIM_PWM_Stop(&htim3, PWM_CHANNEL_1)
#define MOTOR_REV_DISABLE() HAL_TIM_PWM_Stop(&htim3, PWM_CHANNEL_2)

const int16_t PWM_DUTY_MAX = PWM_MAX_PERIOD_COUNT;
volatile static motor_dir_e g_dc_motor_dir;     // 电机运行方向标识

// 推杆长度电机编码器安装方向，磁铁安装不同时有潜在可能会导致编码器输出反向，若反向，可设计为通过调试软件通信修改该变量
static int16_t g_motor_enc_install_dir = -1;    // -1：推杆伸长————编码器计数减少； 1：推杆伸长————编码器计数增加

/**
 * @brief Get the Dc Motor Enc Install Dir object
 * 
 * @return int16_t 获取推杆电机编码器安装方向
 */
int16_t getDcMotorEncInstallDir(void)
{
	return g_motor_enc_install_dir;
}

/**
 * @brief Set the Motor Dir object
 * 
 * @param motor_dir 电机方向, MOTOR_REV = -1, MOTOR_FWD = 1
 */
void setMotorDir(motor_dir_e motor_dir)
{
    g_dc_motor_dir = motor_dir;
}

/**
 * @brief Get the Motor Dir object
 * 
 * @return motor_dir_e 电机方向, MOTOR_REV = -1, MOTOR_FWD = 1
 */
motor_dir_e getMotorDir(void)
{
    return g_dc_motor_dir;
}

/**
 * @brief Set the Motor Enable object
 * 
 */
void setMotorEnable(void)
{
    MOTOR_FWD_ENABLE();
    MOTOR_REV_ENABLE();
}

/**
 * @brief Set the Motor Disable object
 * 
 */
void setMotorDisable(void)
{
    MOTOR_FWD_DISABLE();
    MOTOR_REV_DISABLE();
}

/**
 * @brief Set the Motor Voltage Duty object
 * 
 * @param pwm_duty pwm占空比，参数范围：-PWM_DUTY_MAX ~ PWM_DUTY_MAX，参数为负表示电机反转
 */
void setMotorVoltageDuty(float pwm_duty)
{
    int16_t duty_count = (int16_t)(pwm_duty * PWM_DUTY_MAX);

    duty_count = (abs(duty_count) > PWM_DUTY_MAX) ? PWM_DUTY_MAX : abs(duty_count); // 上限处理

    pwm_duty *= getDcMotorEncInstallDir();
   if (pwm_duty > 0)
   {
       SET_FWD_COMPAER(duty_count); // 设置电压占空比，调节电机电流/速度
       SET_REV_COMPAER(0);
       setMotorDir(MOTOR_FWD);
   }
   else
   {
       SET_REV_COMPAER(duty_count); // 设置电压占空比，调节电机电流/速度
       SET_FWD_COMPAER(0);
       setMotorDir(MOTOR_REV);       
   }
}

